import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import CoreLayout from 'containers/layout'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { protoActions } from 'reduxs'
import { getPostData } from '../../../services/utils'
import { Form, Input, InputNumber, DatePicker, Divider, Button, Select, Radio, Row, Col, Tooltip, Icon, message, Card, Popconfirm, Table, Switch, LocaleProvider, BackTop } from 'antd'
import TagSelect from 'ant-design-pro/lib/TagSelect'
import zhCN from 'antd/lib/locale-provider/zh_CN'
import _ from 'lodash'
import moment from 'moment'
import 'styles/account.scss'

const FormItem = Form.Item
const Option = Select.Option
const RangePicker = DatePicker.RangePicker
const RadioGroup = Radio.Group
const RadioButton = Radio.Button

@connect(
  state => ({
    auth                : state.Passport.auth,
    teams               : state.Passport.teams,
    rtsp_key            : state.Passport.rtsp_key,
    listData            : state.Proto.listData,
    postDataPending     : state.Proto.postDataPending,
    postDataError       : state.Proto.postDataError,
    postDataMessage     : state.Proto.postDataMessage,
    postData            : state.Proto.postData,
    postDataProto       : state.Proto.postDataProto,
    paths               : state.Proto.paths,
    roomfish            : state.Proto.roomfish
  }),
  dispatch => ({
    actions: bindActionCreators({ 
      ...protoActions
    }, dispatch)
  })
)
export default class QueryTable extends PureComponent {

  static propTypes = {
    layoutOptions: PropTypes.object,
    searchOptions: PropTypes.object,
    proto: PropTypes.string,
    tableColumns: PropTypes.arrayOf(PropTypes.object),
    tableScroll: PropTypes.object,
    tablePagination: PropTypes.bool,
    tools: PropTypes.arrayOf(PropTypes.element),
    initialData: PropTypes.bool,
    refresh: PropTypes.bool,
    remark: PropTypes.arrayOf([PropTypes.element, PropTypes.string]),
    tableMode: PropTypes.string,
    tableHeads: PropTypes.array,
    dataFields: PropTypes.array
  }
  
  static defaultProps = {
    layoutOptions: null,
    searchOptions: null,
    proto: undefined,
    tableColumns: [],
    tableScroll: {},
    tablePagination: false,
    tools: [],
    initialData: false,
    refresh: false,
    remark: null,
    tableMode: 'normal',
    tableHeads: null,
    dataFields: undefined
  }

  constructor (props) {
    super(props)
    this.state = {
      pagination: props.tablePagination
    }
    this.container = null
  }

  componentDidMount () {
    const { initialData, proto, rtsp_key } = this.props
    this.props.actions.getlist()
    initialData && this.props.actions.postData(proto, {}, rtsp_key)
  }

  render () {
    const { layoutOptions, searchOptions, postDataPending, postData, proto, tableColumns, tableScroll, tools, refresh, postDataProto, remark, paths, roomfish, tableMode, tableHeads, dataFields } = this.props
    const { PostOptions, BodyData } = getPostData(postData, proto)
    let dataSource = getBaseData(BodyData, dataFields || _.map(tableColumns, 'dataIndex'), tableHeads)
    return (
      <CoreLayout {...layoutOptions}>
        <BackTop 
          visibilityHeight={300}
          target={() => document.querySelector('.layout-page-container')}
          />
        <div ref={ view => this.container = view }>
          <LocaleProvider locale={zhCN}>
            <AdvancedSearchForm 
              Options={searchOptions}
              onSubmit={this.handleSubmit}
              loading={postDataPending && postDataProto === proto}
              Values={PostOptions}
              pagination={this.state.pagination}
              onChangePagination={this.handleChangePagination}
              tools={tools}
              refresh={refresh && (['notice-list'].indexOf(proto) === -1 ? !_.isEmpty(PostOptions) : true)}
              remark={remark}
              paths={paths}
              roomfish={roomfish}
              tableMode={tableMode}
              />
          </LocaleProvider>
          {tableMode === 'listrow' && this.state.pagination ? (
            <div style={{ display: 'flex', flexWrap: 'wrap', flexDirection: 'row' }}>
              {_.isArray(tableHeads) && tableHeads.map((item, i) => {
                let _dataSource = getRowBaseData(item, _.filter(tableColumns, o => o.dataIndex !== 'data_head'), BodyData ? (BodyData[i] || null) : null)
                return (
                  <Table 
                    bordered
                    style={{ marginRight: 15, marginBottom: 15 }}
                    title={() => <span style={{ fontWeight: 800 }}>{item}{_.has(PostOptions, 'end') ? ' - ' + PostOptions['end'] : ''}</span>}
                    dataSource={_dataSource} 
                    columns={[
                      {
                        key: '0',
                        title: '键名',
                        dataIndex: 'data_0',
                        width: 150
                      },
                      {
                        key: '1',
                        title: '键值',
                        dataIndex: 'data_1',
                        width: 150
                      },
                    ]} 
                    pagination={false}
                    loading={postDataPending && postDataProto === proto}
                    />
                )
              })}
            </div>
          ) : (
            <Table 
              bordered
              dataSource={dataSource} 
              columns={tableColumns} 
              pagination={this.state.pagination && tableMode !== 'listrow'}
              loading={postDataPending && postDataProto === proto}
              scroll={tableScroll}
              />
          )}
        </div>
      </CoreLayout>
    )
  }

  handleSubmit = (values) => {
    this.props.actions.postData(this.props.proto, values, this.props.rtsp_key)
  }

  handleChangePagination = (value) => {
    this.setState({ pagination: value })
  }
}

@Form.create()
class AdvancedSearchForm extends PureComponent {

  static propTypes = {
    Options: PropTypes.object,
    onSubmit: PropTypes.func,
    loading: PropTypes.bool,
    Values: PropTypes.object,
    pagination: PropTypes.bool,
    onChangePagination: PropTypes.func,
    tools: PropTypes.arrayOf(PropTypes.element),
    refresh: PropTypes.bool,
    remark: PropTypes.arrayOf(PropTypes.element, PropTypes.string),
    paths: PropTypes.object,
    roomfish: PropTypes.roomfish,
    tableMode: PropTypes.string
  }
  
  static defaultProps = {
    Options: null,
    onSubmit: () => null,
    loading: false,
    Values: {},
    pagination: false,
    onChangePagination: () => null,
    tools: [],
    refresh: false,
    remark: null,
    paths: null,
    roomfish: null,
    tableMode: 'normal'
  }

  state = {
    isRemark: false
  }

  constructor (props) {
    super(props)
    this._Form = null
  }

  render () {
    const { form, Options, loading, Values, pagination, onChangePagination, tools, refresh, remark, paths, roomfish, tableMode } = this.props
    const { getFieldDecorator } = form
    let begin = undefined
    let end = undefined
    let chargeEnd = undefined
    if (_.has(Values, 'begin')) {
      begin = _.has(this.props.Options, 'begin.subtract') ? moment(Values['end']) : moment(Values['begin'])
    }
    if (_.has(Values, 'end')) {
      end = moment(Values['end'])
    }
    if (_.has(Values, 'chargeEnd')) {
      chargeEnd = moment(Values['chargeEnd'])
    }
    let isPaths = false
    let roleIdValue = Values.roleId || ''
    if (_.has(Options, 'roleId.type')) {
      isPaths = Options['roleId']['type'] === 'paths'
      if (isPaths) {
        roleIdValue = Values.roleId || []
      }
    }
    return (
      <div className="ant-advanced-search-form">
        {remark && (
          <div className="content" style={!this.state.isRemark ? { display: 'none' } : null}>
            {remark.map((item, i) => {
              return _.isString(item) 
                ? (
                  <span key={i} style={{ width: 400, lineHeight: 1.8, fontFamily: 'Comic Sans MS' }}>{item}</span>
                )
                : item
            })}
          </div>
        )}{remark && this.state.isRemark && (<Divider dashed />)}
        {!_.isEmpty(Options) && (
          <Form
            layout="inline"
            ref={ ref => this._Form = ref }
            onSubmit={this.handleSubmit}
            >
            <div className="content">
              {_.has(Options, 'begin_end') && (
                <FormItem 
                  style={{ marginLeft: 16 }}
                  label={Options['begin_end'].name}
                  >
                  {getFieldDecorator('begin_end', {
                    rules: [
                      Options['begin_end'].required || {}
                    ],
                    initialValue: begin ? [begin, end] : undefined
                  })(
                      <RangePicker />
                  )}
                </FormItem>
              )}
              {_.has(Options, 'begin') && (
                <FormItem 
                  style={{ marginLeft: 16 }}
                  label={Options['begin'].name}
                  >
                  {getFieldDecorator('begin', {
                    rules: [
                      Options['begin'].required || {}
                    ],
                    initialValue: begin
                  })(
                      <DatePicker />
                  )}
                </FormItem>
              )}
              {_.has(Options, 'chargeEnd') && (
                <FormItem 
                  style={{ marginLeft: 16 }}
                  label={Options['chargeEnd'].name}
                  >
                  {getFieldDecorator('chargeEnd', {
                    rules: [
                      Options['chargeEnd'].required || {}
                    ],
                    initialValue: chargeEnd
                  })(
                      <DatePicker />
                  )}
                </FormItem>
              )}
              {_.has(Options, 'roleId') && (
                <FormItem 
                  style={{ marginLeft: 30 }}
                  label={Options['roleId'].name}
                  >
                  {getFieldDecorator('roleId', {
                    rules: [
                      Options['roleId'].required || {}
                    ],
                    initialValue: roleIdValue
                  })(// roomfish
                    Options['roleId'].type === 'paths' ? (
                      <TagSelect expandable style={{ marginTop: 6, marginLeft: 10 }}>
                        {_.keys(paths).sort().map((key, i) => {
                          return (
                            <TagSelect.Option key={i} value={key}>{paths[key]}</TagSelect.Option>
                          )
                        })}
                      </TagSelect>
                    ) : Options['roleId'].type === 'roomfish' ? (
                      <Select >
                        {_.keys(roomfish).sort().map((key, i) => {
                          return (
                            <Option key={i} value={key}>{roomfish[key]}</Option>
                          )
                        })}
                      </Select>
                    ) : (
                      <Input />
                    )
                  )}
                </FormItem>
              )}
              {_.keys(Options).length > 0 && !isPaths && (
                <FormItem style={{ marginLeft: 20 }}>
                  <Button 
                    type="primary" 
                    htmlType="submit" 
                    loading={loading} 
                    >
                    查询
                  </Button>
                </FormItem>
              )}
            </div>
          </Form>
        )}
        {!_.isEmpty(Options) && (<Divider dashed style={{ marginTop: 0 }} />)}
        <Row>
          <Col span={20}>
            <Form layout="inline">
              <div className="content">
                {_.keys(Options).length > 0 && isPaths && (
                  <FormItem style={{ marginBottom: 0 }}>
                    <Button 
                      type="primary" 
                      onClick={() => this._Form.props.onSubmit()}
                      loading={loading} 
                      >
                      查询
                    </Button>
                  </FormItem>
                )}
                <FormItem style={{ marginBottom: 0 }}>
                  {tools.map((item, i) => {
                    return item
                  })}
                </FormItem>
                <FormItem 
                  style={{ marginBottom: 0 }}
                  label={tableMode === 'listrow' ? '分列显示' : '分页显示'}
                  >
                  <Switch
                    checked={pagination}
                    onChange={onChangePagination}
                    />
                </FormItem>
                {remark && (
                  <FormItem 
                    style={{ marginBottom: 0 }}
                    label="查看备注"
                    >
                    <Switch
                      checked={this.state.isRemark}
                      onChange={() => this.setState({ isRemark: !this.state.isRemark })}
                      />
                  </FormItem>
                )}
              </div>
            </Form>
          </Col>
          <Col span={4} style={{ textAlign: 'right' }}>
            <Tooltip title="刷新">
              {refresh && (
                <Button shape="circle" style={{ border: 0, marginTop: 5 }} onClick={this.handleRefresh}>
                  <Icon type="sync" spin={loading} />
                </Button>
              )}
            </Tooltip>
          </Col>
        </Row>
      </div>
    )
  }

  handleSubmit = (e) => {
    e && e.preventDefault()
    this.props.form.validateFields((err, values) => {
      if (!err) {
        if (_.has(values, 'begin')) {
          if (_.has(this.props.Options['begin'], 'subtract')) {
            let dateFormat = this.props.Options['begin'].format
            values['end'] = moment(values['begin']).format(dateFormat)
            values['begin'] = moment(values['begin']).subtract(...this.props.Options['begin']['subtract']).format(dateFormat)
          }
          else {
            values['begin'] = moment(values['begin']).format(this.props.Options['begin'].format)
          }
        }
        if (_.has(values, 'begin_end')) {
          let { begin, end } = _.zipObject(['begin', 'end'], values['begin_end'])
          values['begin'] = moment(begin).format(this.props.Options['begin_end'].format)
          values['end'] = moment(end).format(this.props.Options['begin_end'].format)
          _.unset(values, 'begin_end')
        }
        if (_.has(values, 'chargeEnd')) {
          values['chargeEnd'] = moment(values['chargeEnd']).format(this.props.Options['chargeEnd'].format)
        }
        this.props.onSubmit(values)
      }
    })
  }

  handleRefresh = this.handleSubmit
  
}

const getBaseData = (data, fields, heads = null) => {
  let list = []
  _.forEach(data || [], (value, key) => {
    let head = _.isArray(heads) ? `${heads[key] || '#'};` : ''
    list.push({
      key: key,
      ..._.zipObject(fields, `${head}${value}`.split(/\;/))
    })
  })
  return list
}

const getRowBaseData = (name, fields, data) => {
  let list = []
  let n = 0
  let _data = data ? data.split(/\;/) : []
  for (let item of fields) {
    list.push({
      key: item.key,
      ['data_0']: item.title,
      ['data_1']: _data[n] || '--'
    })
    n++
  }
  return list
}